pub mod a {
    #[non_exhaustive]
    pub struct S {
        pub field: i32,
        pub new_field: i32,
    }

    #[non_exhaustive]
    pub enum AdmitMoreVariants {
        VariantA,
        VariantB,
        #[non_exhaustive]
        VariantC {
            a: String,
        },
        VariantD,
    }

    #[allow(dead_code)]
    pub fn create_mod_a_s(field: i32) -> S {
        S {
            field,
            new_field: 0,
        }
    }

    #[allow(dead_code)]
    pub fn create_variant_a() -> AdmitMoreVariants {
        AdmitMoreVariants::VariantA
    }

    #[allow(dead_code)]
    pub fn create_variant_b() -> AdmitMoreVariants {
        AdmitMoreVariants::VariantB
    }

    #[allow(dead_code)]
    pub fn create_variant_c() -> AdmitMoreVariants {
        AdmitMoreVariants::VariantC {
            a: "variant-c-value".to_string(),
        }
    }

    #[allow(dead_code)]
    pub fn create_variant_d() -> AdmitMoreVariants {
        AdmitMoreVariants::VariantD
    }
}

pub mod b {
    #[non_exhaustive]
    #[allow(clippy::manual_non_exhaustive)]
    pub struct S {
        pub a: i32,
        // Because `b` is private, you cannot match on `S` without using `..` and `S`
        //  cannot be directly instantiated or matched against.
        _b: (),
    }

    #[allow(dead_code)]
    pub fn create_mod_b_s(a: i32) -> S {
        S { a, _b: () }
    }
}

#[test]
fn mod_a_s_struct() {
    // Non-exhaustive structs can be constructed as normal within the defining crate.
    let s = a::S {
        field: 1,
        new_field: 2,
    };

    assert_eq!(1, s.field);
    assert_eq!(2, s.new_field);
}

#[test]
fn create_mod_a_s_struct() {
    let s = a::create_mod_a_s(1);

    assert_eq!(1, s.field);
    assert_eq!(0, s.new_field);
}

#[test]
fn create_mod_b_s_struct() {
    let s = b::create_mod_b_s(1);

    assert_eq!(1, s.a);

    let b::S { a: a_copy, .. } = s;

    assert_eq!(1, a_copy);
}

#[test]
fn create_variant_a() {
    let res = a::create_variant_a();

    match res {
        a::AdmitMoreVariants::VariantA => (),
        _ => panic!("Expected AdmitMoreVariants::A"),
    }
}

#[test]
fn create_variant_b() {
    let res = a::create_variant_b();

    match res {
        a::AdmitMoreVariants::VariantB => (),
        _ => panic!("Expected AdmitMoreVariants::B"),
    }
}

#[test]
fn create_variant_c() {
    let res = a::create_variant_c();

    match res {
        a::AdmitMoreVariants::VariantC { a: a_copy } => {
            assert_eq!("variant-c-value".to_string(), a_copy)
        }
        _ => panic!("Expected AdmitMoreVariants::C"),
    }
}

#[test]
fn create_variant_d() {
    let res = a::create_variant_d();

    match res {
        a::AdmitMoreVariants::VariantD => (),
        _ => panic!("Expected AdmitMoreVariants::D"),
    }
}
